﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace BaseHelper.Net
{
    public class TcpServerHelper
    {
        public enum ClientState
        {
            None, Online, OffLine
        }
        public event TcpClientHelper.DataArriveHandler DataArriveEvent;

        public delegate void ClientStateHandler(string remoteIP, ClientState state);
        public static event ClientStateHandler ClientStateEvent;

        private ConcurrentDictionary<string, TcpClientHelper> _slClient = new ConcurrentDictionary<string, TcpClientHelper>();
        private TcpListener _tcpListener;
        private Thread _thListener;

        private string _error;

        public string Error
        {
            set { _error = value; }
            get { return _error; }
        }


        public bool Start(int port)
        {
            if (_thListener != null)
            {
                _thListener.Abort();
                _thListener = null;
            }
            if (_tcpListener != null)
            {
                _tcpListener.Stop();
                _tcpListener = null;
            }

            _tcpListener = new TcpListener(IPAddress.Any, port);
            try
            {
                _tcpListener.Start();
                _thListener = new Thread(thListener);
                _thListener.Start();
                return true;
            }
            catch { }
            return false;

        }

        private void thListener()
        {

            while (_tcpListener != null)
            {
                TcpClient client = _tcpListener.AcceptTcpClient();
                string ipeo = client.Client.RemoteEndPoint.ToString();

                _slClient[ipeo] = new TcpClientHelper();
                _slClient[ipeo].DataArriveEvent += new TcpClientHelper.DataArriveHandler(TcpServerHelper_DataArriveEvent);
                _slClient[ipeo].DisconnectEvent += new TcpClientHelper.DisconnectHandler(TcpServerHelper_DisconnectEvent);
                _slClient[ipeo].Bind(client);

                if (ClientStateEvent != null)
                    ClientStateEvent(ipeo, ClientState.Online);
            }
        }

        private void TcpServerHelper_DataArriveEvent(string remoteIP, byte[] buffer, int len)
        {
            if (DataArriveEvent != null)
                DataArriveEvent(remoteIP, buffer, len);

        }

        public bool SendBytes(string remoteIP, byte[] buffer)
        {
            try
            {
                this.Error = "";
                TcpClientHelper tcp;
                if (_slClient.ContainsKey(remoteIP) && _slClient.TryGetValue(remoteIP, out tcp))
                {
                    return tcp.SendBytes(buffer);
                }
                else
                    this.Error = "该主机不存在！";

            }
            catch (Exception ex)
            {
                this.Error = ex.Message;
            }
            return false;
        }






        private void TcpServerHelper_DisconnectEvent(string remoteIP)
        {
            TcpClientHelper tcp;
            if (_slClient.ContainsKey(remoteIP) && _slClient.TryRemove(remoteIP, out tcp))
            {
                //啥都不用做
            }
            if (ClientStateEvent != null)
                ClientStateEvent(remoteIP, ClientState.OffLine);
        }

    }
}
